package com.lwl.mini.session;

import com.lwl.mini.binding.MapperProxyFactory;
import com.lwl.mini.binding.MapperRegistry;
import com.lwl.mini.executor.DefaultExecutor;
import com.lwl.mini.executor.Executor;
import com.lwl.mini.executor.ResultMapping;
import com.lwl.mini.executor.statement.DefaultStatementHandler;
import com.lwl.mini.executor.statement.StatementHandler;
import com.lwl.mini.mapping.Environment;
import com.lwl.mini.mapping.MapperStatement;
import com.lwl.mini.plugin.DefaultFilter;
import com.lwl.mini.plugin.Filter;
import com.lwl.mini.plugin.FilterChain;
import com.lwl.mini.transaction.Transaction;
import com.lwl.mini.util.ObjectUtils;
import lombok.Data;
import lombok.Getter;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author lwl
 * @create 2022/4/9 12:35
 */
@Data
public class Configuration {

    private final static Configuration INSTANCE = new Configuration();

    protected final MapperRegistry mapperRegistry = new MapperRegistry(this);

    public static Configuration getInstance(){
        return INSTANCE;
    }

    /**
     * 连接环境
     */
    private Environment environment;
    /**
     * 对应配置文件中的properties标签
     */
    private Properties properties;

    /**
     * 对应配置文件中的settings标签
     */
    private Map<String,Boolean> settings;

    /**
     * 对应配置文件中的mapper标签
     */
    private Map<String,String> mappers;

    /**
     * 类信息和相对应的代理工厂的集合
     */
    private Map<Class<?>, MapperProxyFactory<?>> knownMappers;

    /**
     * 责任链模式
     * 用于执行器执行时调用
     */
    private final FilterChain chain = new FilterChain();

    private Configuration(){
        //setting初始化
        settingInit();
        //mapper的初始化
        mapperInit();
    }

    private void settingInit(){
        settings = new HashMap<>();
        //赋默认值
        //是否开启缓存,默认开启
        settings.put("cacheEnable",true);
        //是否开启日志记录,默认不开启
        settings.put("loggedEnable",false);
        //是否使用默认的Druid连接池,false则使用JDBC
        settings.put("userDruid",true);
    }

    private void mapperInit(){
        //Mapper包的类路径
        mappers = new HashMap<>();
        mappers.put("package",null);
    }

    public void addMappers(String packName){
        if(!ObjectUtils.StringIsEmpty(packName)){
            mapperRegistry.addMappers(packName);
        }
    }

    public Executor newExecutor(Transaction transaction){
        Executor executor = new DefaultExecutor(this,transaction);
        Filter filter = new DefaultFilter();
        chain.addFilter(filter);
        //责任链模式
        executor = (Executor) chain.doFilter(executor);
        return executor;
    }

    public <T> T getMapper(Class<T> type, DefaultSqlSession sqlSession) {
        return mapperRegistry.getMapper(type,sqlSession);
    }

    public MapperStatement newMapperStatement(String statement, Map<Object,Object> paramMap, Class<? extends Object> returnType, Method method){
        return new MapperStatement(statement,paramMap,returnType,method);
    }

    public StatementHandler newStatementHandler(MapperStatement statement) {
        return new DefaultStatementHandler(statement);
    }

    public ResultMapping newResultMapping(String columnName, Field field, Method executeMethod) throws SQLException {
        return  new ResultMapping(columnName,field,executeMethod);
    }
}


